#pragma once

#include <Windows.h>
#include <process.h>
#include <vector>
#include <concurrent_vector.h>

class Renderer;

enum MsgType
{
	MSG_BodyInfo,
	MSG_SPRINGINFO,
	MSG_TOGGLESPRING,
	MSG_SPRINGACTIVE,
	MSG_NEWCIRCLE,
	MSG_MORECIRCLES,
	MSG_NEWAIRJET,
	MSG_STATS,
	MSG_UPD_ELASTICITY,
	MSG_UPD_FRICTION,
	MSG_UPD_PAUSE,
	MSG_UPD_GRAPHICSFREQ,
	MSG_UPD_NETWORK_FREQ,
	MSG_UPD_PHYSICS_FREQ
};

struct Header
{
	MsgType type;
	int		length;
};

struct Message
{
	Header	header;
	void*	data;
};

class Connection
{
	public:
		Connection()	: m_bTerminate(false), mTotalObjects(0), mConnected(false) {} 
		~Connection()	{}

		void			start(SOCKET s, unsigned int id);
		void			waitForTermination();

		void			terminate();
		bool			isTerminated() const;

		void			setReceiveBuffer(void* data); 
		void			setRopeReceiveBuffer(void* data);

		void			sendMessage(Message msg); 

		void			startTimer();
		double			getDeltaTime();
		double			getTime();

		int*			m_objectsReceived;
		int*			m_ropePoints;
		float*			m_objectsPerSecond;

		Renderer*		m_renderer;

	private:
		bool			findServer(int& tcpPort, sockaddr_in& serverAddr);
		bool			updateServer();
		void			reconnect();
		bool			receive(SOCKET socket, char* data, int size);
		int				init();
		int				sendData();
		int				receiveData();

		SOCKET			s;
		bool			mConnected;
		int				mTotalObjects;
		
		__int64			tmr_start;
		double			freq;	

		

		void*			m_rcvBuffer;
		void*			m_rcvRopeBuffer;

		unsigned int	m_Id;

		bool			m_bTerminate;

		HANDLE			m_hSend;
		HANDLE			m_hReceive;

		SOCKET			m_socket;


		Concurrency::concurrent_vector<Message> m_msgQueue;

		static unsigned __stdcall threadSend(void* param) {
			if (param)
				return ((Connection*)param)->sendData();
			return 1;
		}

		static unsigned __stdcall threadReceive(void* param) {
			if (param)
				return ((Connection*)param)->receiveData();
			return 1;
		}
};